package com.zhiwu.uhf.ui.fragment;

import static com.zhiwu.uhf.KeyData.URL_UPLOAD;
import static com.zhiwu.uhf.util.Base64Util.decodeToString;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.uhf.api.cls.Reader;
import com.zhiwu.uhf.MainActivity;
import com.zhiwu.uhf.R;
import com.zhiwu.uhf.adapter.EpcListAdapter;
import com.zhiwu.uhf.data.PublicData;
import com.zhiwu.uhf.entity.BeanInfo;
import com.zhiwu.uhf.entity.ComparedInfo;
import com.zhiwu.uhf.ui.base.BaseFragment;
import com.zhiwu.uhf.util.DataInterface;
import com.zhiwu.uhf.util.GsonTypeAdapterFactory;
import com.zhiwu.uhf.util.LogUtil;
import com.zhiwu.uhf.util.TagUtil;
import com.zhiwu.uhf.util.UtilSound;

import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cn.pda.serialport.Tools;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

public class EpcListFragment extends BaseFragment {

    @BindView(R.id.button_inventory)
    Button btnInventory ;
    @BindView(R.id.button_upload)
    Button btnUpload;
    @BindView(R.id.button_clean)
    Button btnClean ;
    @BindView(R.id.checkbox_exclude)
    CheckBox cbExclude ;
    @BindView(R.id.recycle)
    RecyclerView recycle;
    private EpcListAdapter epcListViewAdapter ;
    private List<String> tagIdList = new ArrayList<>();
    private Map<String, Integer> tagMap = new LinkedHashMap();
    private MainActivity mainActivity ;
    private Handler soundHandler = new Handler();
    private Runnable soundTask = null ;
    private boolean isReader = false;
    private Timer timer ;
    private KeyReceiver keyReceiver;

    private boolean isMulti = false;// multi mode flag

    private final int MSG_INVENTORY = 1 ;
    private final int MSG_INVENTORY_TIME = 1001 ;
    private final int MSG_SCAN_ENABLED = 1002;

    private int uploaded = 0;
    private int uploadedFail = 0;
    private int totalUploaded = 0;

    private int found = 0;
    private int total = 0;
    private boolean onlyShowGreen = false;

    public static List<ComparedInfo> resultList = new ArrayList<>();


    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private Gson gson = new GsonBuilder().registerTypeAdapterFactory(new GsonTypeAdapterFactory()).create();

    private Handler handler = new Handler(){
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case MSG_INVENTORY:
                    cartonNo();
                    break ;
                case MSG_SCAN_ENABLED:

//                    setEnabled(!checkedList.isEmpty());
                    break ;
            }
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_epc_list, container, false) ;
        ButterKnife.bind(this, view);
        initView();
        UtilSound.initSoundPool(mainActivity);
        return view;
    }

    private void initView() {
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recycle.setLayoutManager(layoutManager);
        recycle.setHasFixedSize(true);
        recycle.setItemAnimator(null);
        epcListViewAdapter = new EpcListAdapter(getActivity(), resultList);
        recycle.setAdapter(epcListViewAdapter);
        init();
    }
    void init(){
        setUploadEnabled(false);
        //TODO 测试数据
//        for(int i = 0; i< 300;i++) {
//            ComparedInfo comparedInfo = new ComparedInfo();
//            comparedInfo.setContainer("00000" + (i+1));
//            if(i%5!=0) {
//                comparedInfo.setRouteName("线路" + (i+1));
//                comparedInfo.setRouteCode("routeCode" + (i+1));
//            }
//            PublicData.comparedList.add(comparedInfo);
//        }
        //TODO 测试数据
        for(BeanInfo.Data data: PublicData.checkedList) {
            total += data.getTotal();
        }
        setTitle("入库(" + found + "/" + total + ")");
        inventory();
        itemclick();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mainActivity = (MainActivity) getActivity();

    }

    @Override
    public void onResume() {
        super.onResume();
        Log.e("pang", "onResume()");
        if (mainActivity.mUhfrManager != null) {
            mainActivity.mUhfrManager.setCancleInventoryFilter();
        }
        //
        registerKeyCodeReceiver();
        //getModuleInfo() ;
        // FastId功能开启时，不允许开启附加TID数据功能，两者有冲突
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.e("pang", "onPause()");
        stopInventory();
        //
        mainActivity.unregisterReceiver(keyReceiver);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        clearData();
        PublicData.checkedMap.clear();
        PublicData.checkedList.clear();
        stopInventory();

    }
    private void setTitle(String title) {

        ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(title);
    }
//    int index = 0;
    private Runnable inventoryThread = new Runnable() {
        @Override
        public void run() {
            LogUtil.e("inventoryThread is running");
            List<Reader.TAGINFO> listTag = null;
            if (isMulti) {
                listTag = mainActivity.mUhfrManager.tagInventoryRealTime();
            }else{
                listTag = mainActivity.mUhfrManager.tagInventoryByTimer((short) 50); ;
            }
            if (listTag == null) {
                LogUtil.e("listTag = null");
            }
            if (listTag != null && !listTag.isEmpty()) {
                LogUtil.e("inventory listTag size = " + listTag.size());
                UtilSound.play(1,0);
                for (Reader.TAGINFO taginfo : listTag) {
                    String epcAndTid = Tools.Bytes2HexString(taginfo.EpcId, taginfo.EpcId.length);
                    if(epcAndTid.length() < 6) {
                        continue;
                    }
                    String containerId = TagUtil.Hex2Hex4NoSecrate(epcAndTid);
                    tagMap.put(containerId, 1);

                }
                handler.sendEmptyMessage(MSG_INVENTORY);
            }
            //--start 模拟数据
//            for (int i = 0; i < 10; i++) {
//                String containerId = "";
//                if(index<10) {
//                    containerId = "00000" + index;
//                } else if (index < 100) {
//                    containerId = "0000" + index;
//                } else if (index < 1000) {
//                    containerId = "000" + index;
//                } else {
//                    index = 0;
//                }
//                tagMap.put(containerId, 1);
//                index++;
//            }
//            handler.sendEmptyMessage(MSG_INVENTORY);
            //--end 模拟数据

            //这里暂时先这样
            if(true) {
//            if (checkBoxLoop.isChecked()) {
                handler.postDelayed(inventoryThread, 500) ;
            }else{
                if(timer != null){
                    timer.cancel();
                    timer = null ;
                }
                handler.sendEmptyMessage(MSG_INVENTORY_TIME);
                isReader = false ;
            }

        }
    };

    @OnClick(R.id.button_clean)
    public void clear() {
        if (isFastClick()){
            clearData();
            setUploadEnabled(false) ;
            epcListViewAdapter.notifyDataSetChanged();
        }
    }

    private void clearData() {
        found = 0;
        resultList.clear();
        PublicData.comparedList.clear();
        PublicData.comparedGreenList.clear();
        PublicData.comparedMap.clear();
        tagMap.clear();
        tagIdList.clear();
    }

    private final static int MIN_CLICK_DELAY_TIME = 1500;
    private static long lastClickTime;
    public static boolean isFastClick() {
        boolean flag = false;
        long curClickTime = System.currentTimeMillis();
        if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
            flag = true;
        }
        lastClickTime = curClickTime;
        return flag;
    }
    @OnClick(R.id.button_inventory)
    public void inventory() {
        //操作之前判定模块是否正常初始化
        //todo 模拟数据时需要注释
        if(mainActivity.mUhfrManager == null){
            showToast(R.string.communication_timeout);
            return ;
        }
        if (!isReader) {
            inventoryEPC();
        }else{
            stopInventory() ;
        }

    }

    private void inventoryEPC() {
        isReader = true ;
        resultList.clear();
        PublicData.comparedList.clear();
        PublicData.comparedGreenList.clear();
        PublicData.comparedMap.clear();
        found = 0;
        btnInventory.setText(R.string.stop_inventory);
//            soundTask();
        showToast(R.string.start_inventory);
        //
        if(mainActivity.mUhfrManager != null) {
            if(mainActivity.mUhfrManager.getGen2session()!=3){

                mainActivity.mUhfrManager.setGen2session(isMulti);

            }
            if (isMulti) {
                mainActivity.mUhfrManager.asyncStartReading() ;

            }
        }

        if (timer == null) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    handler.sendEmptyMessage(MSG_INVENTORY_TIME);
                }
            }, 1000, 1000);
        }

        //启动盘存线程
        handler.postDelayed(inventoryThread, 0);
    }


    private void stopInventory()  {
        if (mainActivity.isConnectUHF) {
            if(isReader){
                handler.removeCallbacks(inventoryThread);
                soundHandler.removeCallbacks(soundTask);
                isReader = false ;
                if (timer != null) {
                    timer.cancel();
                    timer = null ;
                }

                btnInventory.setText(R.string.start_inventory_base);
            }

        } else {
            showToast(R.string.communication_timeout);
        }
        isReader = false ;
    }
    @OnClick(R.id.button_upload)
    public void clickUpload() {
        uploaded = 0;
        uploadedFail = 0;
        totalUploaded = 0;
        Map<String, Integer> compared = new HashMap<>();
        String unComparedContainers = "";
        int unComparedCount=0;
        for(ComparedInfo comparedInfo : PublicData.comparedList) {
            if(comparedInfo.getRouteCode() != null) {
                compared.put(comparedInfo.getRouteCode(), 1);
            } else {
                unComparedContainers += comparedInfo.getContainer();
                unComparedContainers += ",";
                unComparedCount++;
            }
        }
        totalUploaded = compared.keySet().size();
        //如果包含没有匹配的箱号，也可上传
        if(StringUtils.isNoneBlank(unComparedContainers)) {
            totalUploaded++;
        }
        if(totalUploaded == 0) {
            getActivity().runOnUiThread(() -> showToast("未匹配线路"));
            return;
        }
        //上传匹配的线路
        for(BeanInfo.Data data : PublicData.checkedList) {
            upload(data);
        }
        //上传未匹配的线路
        if(StringUtils.isNoneBlank(unComparedContainers)) {
            uploadUnCompared(unComparedContainers, unComparedCount);
        }

    }
    private void uploadUnCompared(String containers, int count) {
        Date curDate =  new Date(System.currentTimeMillis());
        String time  = dateFormat.format(curDate);
        containers = containers.substring(0, containers.length() -1);
        Call call = new DataInterface().Upload(null,containers, count, time,URL_UPLOAD);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                uploadedFail++;
                Log.i("tag", "----Upload----"+e);
                getActivity().runOnUiThread(() -> showToast(e+""));
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    uploaded ++;
                    String Str = response.body().string();
                    uploadData(Str);
                }else {
                    uploadedFail++;
                    getActivity().runOnUiThread(() -> showToast("Upload_failed"));
                }
            }
        });
    }
    private void upload(BeanInfo.Data data) {
        Date curDate =  new Date(System.currentTimeMillis());
        String time  = dateFormat.format(curDate);
        //这里只上传勾选的

        Map<String, Integer> comparedMap = PublicData.routeMap.get(data.getRoute_code());
        //没有匹配到，直接返回
        if(comparedMap == null || comparedMap.isEmpty()) {
            return;
        }
        int count = 0;
        String containers = "";
        for (Map.Entry<String, Integer> entry : comparedMap.entrySet()) {
            if(entry.getValue() == 1) {
                count++;
                containers += entry.getKey();
                containers += ",";
            }
        }
        if("".equals(containers)) {
            return;
        }
        containers = containers.substring(0, containers.length() -1);
        Call call = new DataInterface().Upload(data,containers, count, time,URL_UPLOAD);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                uploadedFail++;
                Log.i("tag", "----Upload----"+e);
                getActivity().runOnUiThread(() -> showToast(e+""));
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    uploaded ++;
                    String Str = response.body().string();
                    uploadData(Str);
                }else {
                    uploadedFail++;
                    getActivity().runOnUiThread(() -> showToast("Upload_failed"));
                }
            }
        });
    }
    private void uploadData(String str) {
        BeanInfo beanInfo = gson.fromJson(str,BeanInfo.class);
        if ("1".equals(beanInfo.getStatus())){
            getActivity().runOnUiThread(() -> showToast("上传成功:" + uploaded + "/" + totalUploaded + (uploadedFail > 0 ? (" 上传失败:" + uploadedFail) : "")));
        }else {
            getActivity().runOnUiThread(() -> showToast(decodeToString(beanInfo.getMsg())));
        }
    }

    private void itemclick() {

        epcListViewAdapter.setOnItemmultiple((view, data, position) -> {
            handler.sendEmptyMessage(MSG_SCAN_ENABLED);
            epcListViewAdapter.notifyDataSetChanged();
        });
        cbExclude.setOnCheckedChangeListener((buttonView, isChecked) -> {
            cbExclude(isChecked);
        });
    }
    public void cbExclude(boolean isChecked) {
        onlyShowGreen = isChecked;
        resultList.clear();
        if(onlyShowGreen) {
            resultList.addAll(PublicData.comparedGreenList);
        } else {
            resultList.addAll(PublicData.comparedList);
        }
        epcListViewAdapter.notifyDataSetChanged();
    }
    /**
     * 获取接口4数据
     * 获取接口3数据，选择item后（多选），点击扫描获取Epc
     * Epc前6位与接口4getContainers所有数据对比，若包含再用接口4getRoute_code与接口3getRoute_code对比，若一致，形成绑定
     * 上传
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
   private void cartonNo(){
        tagIdList.clear();
        for(String containerId :tagMap.keySet()) {
            if(!PublicData.comparedMap.containsKey(containerId)) {
                PublicData.comparedMap.put(containerId, 0);
                tagIdList.add(containerId);
            }
        }
        if (!tagIdList.isEmpty()){
            for(String container : tagIdList) {
                //得到线路code
                String routeCode = PublicData.epcMap.get(container);
                if(routeCode != null && routeCode.length() != 0 && PublicData.checkedMap.containsKey(routeCode)) {
                    //得到该线路所有箱号
                    Map<String, Integer> comparedContainer = PublicData.routeMap.get(routeCode);
                    //设置该箱号为匹配状态
                    comparedContainer.put(container, 1);
                    //设置改箱号已匹配
                    PublicData.comparedMap.put(container, 1);
                    found++;
                    //保存已经匹配的列表
                    ComparedInfo comparedInfo = new ComparedInfo();
                    comparedInfo.setRouteCode(routeCode);
                    comparedInfo.setRouteName(PublicData.routeCodeNameMap.get(routeCode));
                    comparedInfo.setContainer(container);
                    PublicData.comparedList.add(0, comparedInfo);
                    PublicData.comparedGreenList.add(0, comparedInfo);
                    resultList.add(0, comparedInfo);
                } else {
                    //未找到线路 只保存箱号 显示的时候标红
                    ComparedInfo comparedInfo = new ComparedInfo();
                    comparedInfo.setContainer(container);
                    PublicData.comparedList.add(0, comparedInfo);
                    //如果没有选中
                    if(!onlyShowGreen) {
                        resultList.add(0, comparedInfo);
                    }
                }
            }
            //这里刷新页面
            setTitle("入库(" + found + "/" + total + ")");
            setUploadEnabled(true);
            epcListViewAdapter.notifyDataSetChanged();
        }
      }

    private void registerKeyCodeReceiver() {
        keyReceiver = new KeyReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.rfid.FUN_KEY");
        filter.addAction("android.intent.action.FUN_KEY");
        mainActivity.registerReceiver(keyReceiver, filter);
    }

    private class KeyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int keyCode = intent.getIntExtra("keyCode", 0);
            LogUtil.e("keyCode = " + keyCode);
            if (keyCode == 0) {
                keyCode = intent.getIntExtra("keycode", 0);
            }
            boolean keyDown = intent.getBooleanExtra("keydown", false);
            if (keyDown) {
//                ToastUtils.showText("KeyReceiver:keyCode = down" + keyCode);
            } else {
//                ToastUtils.showText("KeyReceiver:keyCode = up" + keyCode);
                switch (keyCode) {
                    case KeyEvent.KEYCODE_F1:
                        break;
                    case KeyEvent.KEYCODE_F2:
                        break;
                    case KeyEvent.KEYCODE_F5:
                        break;
                    case KeyEvent.KEYCODE_F3://C510x
                    case KeyEvent.KEYCODE_F4://6100
                    case KeyEvent.KEYCODE_F7://H3100
                        inventory();
                        break;
                }
            }
        }

    }


    private void setUploadEnabled(boolean isEnable) {
        btnUpload.setEnabled(isEnable);

    }

}